package client;

import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.sql.SQLException;
import java.util.LinkedList;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;


import server.Marketplace;

import common.Item;
import common.ItemImpl;

@SuppressWarnings("serial")
public class TraderImpl extends UnicastRemoteObject implements Trader {
	private String traderName, traderPassword;
	private Marketplace marketPlace;
	public View view;
	private String message;
	
	public TraderImpl(String traderName, String traderPassword, Marketplace marketplace) throws RemoteException, MalformedURLException, NotBoundException {
		super();
		this.marketPlace = marketplace;
		this.traderName = traderName;
		this.traderPassword = traderPassword;
	}

	@Override
	public void itemSold(Item soldItem) throws RemoteException {
		message = "Your item " + soldItem.getName() + "  sold. $" + soldItem.getPrice() + " deposited to your account.";
		
		java.awt.EventQueue.invokeLater(new Runnable() {
	        public void run() {
	    		if (!SwingUtilities.isEventDispatchThread())
	    			throw new IllegalStateException("Must use swing event thread");
	    		JOptionPane.showMessageDialog(null, message, "Item sold", JOptionPane.INFORMATION_MESSAGE);
	        }
		});
		
	}

	@Override
	public void itemAvaliable(Item avaliableItem) throws RemoteException {
		String message = "The item " + avaliableItem.getName() + "  is avaliable in store. Price: $" + avaliableItem.getPrice();
		System.out.println("Item available " + message);
		java.awt.EventQueue.invokeLater(new ItemAvailable(message));
		

	}
	
	@Override
	public String getTraderName(){
		return traderName;
	}
	
	@Override
	public String getTraderPassword(){
		return traderPassword;
	}
	
	public void buy(Item item) throws SQLException{
		try {
			System.out.println("Buying item " + item.getInfoStr());
			boolean success = marketPlace.buyItem(item, getTraderName());
			if (success)
			{
				message = "You bought " + item.getName() + " for $" + item.getPrice() + " from " + item.getOwner();
				java.awt.EventQueue.invokeLater(new Runnable() {
			        public void run() {
			    		JOptionPane.showMessageDialog(null, message, "Purchase successful", JOptionPane.INFORMATION_MESSAGE);
			        }
				});
			} else
			{
				message = "Failed to buy item, item still available?";
				java.awt.EventQueue.invokeLater(new Runnable() {
			        public void run() {
			    		JOptionPane.showMessageDialog(null, message, "Purchase unsuccessful", JOptionPane.ERROR_MESSAGE);
			        }
				});
			}
			
		} catch (RemoteException e) {
			message = e.getMessage();
			System.out.println(message);
			Throwable t = e.getCause();
			//TODO IMPLEMENT WITH NEW BANK FILES
			/*
			if (t.getCause() instanceof Rejected)
			{
				java.awt.EventQueue.invokeLater(new Runnable() {
			        public void run() {
			    		JOptionPane.showMessageDialog(null, message, "Purchase error", JOptionPane.ERROR_MESSAGE);
			        }
				});
			} else
				e.printStackTrace(); */
		} 
		
	}
	
	public void sell(String itemName, float price) throws RemoteException, SQLException{
		Item itemToSell = new ItemImpl(traderName, itemName, price);
		try {
			marketPlace.sellItem(itemToSell);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}
	
	public void watch(String itemName, float maxPrice) throws SQLException{
		try {
			marketPlace.watchForItem(itemName, maxPrice, traderName);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}
	
	public LinkedList<Item> updateItemsList() throws SQLException{
		LinkedList<Item> list = null;
		try {
			list = removeSelfFromList(marketPlace.getItems().getList());
			if (list.size() == 0)
			{
				System.out.println("List was empty");
			} else
				System.out.println("List received, first item: " + list.getFirst().getInfoStr());
				
		} catch (RemoteException e) {
			System.out.println(e);
		}
		
		return list;
	}
	
	public float getAccountBalance() throws RemoteException {
		return marketPlace.getAccountBalance(this.getTraderName());
	}
	
	public int getItemsBought() throws RemoteException, SQLException {
		return marketPlace.getItemsBought(traderName);
	}

	public int getItemsSold() throws RemoteException, SQLException {
		return marketPlace.getItemsSold(traderName);
	}	
	
	private LinkedList<Item> removeSelfFromList(LinkedList<Item> inList) throws RemoteException {
		LinkedList<Item> outList = new LinkedList<Item>();
		for(int i = 0; i < inList.size(); i++){
			if (!inList.get(i).getOwner().equalsIgnoreCase(traderName))
				outList.add(inList.get(i));
		}
		return outList;
	}

}
